package pl.wroc.uni.ii.evolution.solutionspaces;

import java.util.Set;

import pl.wroc.uni.ii.evolution.engine.individuals.EvRealVectorIndividual;
import pl.wroc.uni.ii.evolution.engine.prototype.EvObjectiveFunction;
import pl.wroc.uni.ii.evolution.engine.prototype.EvSolutionSpace;

/** 
 * A solution space of EvRealVectorIndividuals
 * 
 * @author Marcin Golebiowski
 */
public class EvRealVectorSpace implements EvSolutionSpace<EvRealVectorIndividual> {

  private static final long serialVersionUID = 8279690263081096298L;

  private EvObjectiveFunction<EvRealVectorIndividual> objective_function;
  
  protected int dimension;
  
  /** 
   * 
   * @param i number of individuals chromosome dimension (length).
   */
  public EvRealVectorSpace(EvObjectiveFunction<EvRealVectorIndividual> objective_function, int i) {
    setObjectiveFuntion(objective_function);
    dimension = i;
  }

  /**
   * @return true if only individual is from correct class and dimension 
   */
  public boolean belongsTo(EvRealVectorIndividual individual) {
    return true;
  }

  public Set<EvSolutionSpace<EvRealVectorIndividual>> divide(int n) {
    //TODO implement
    return null;
  }

  public Set<EvSolutionSpace<EvRealVectorIndividual>> divide(int n, Set<EvRealVectorIndividual> p) {
    return null;
  }

  /**
   * Generates random BinaryIndividual.
   */
  public EvRealVectorIndividual generateIndividual() {
    EvRealVectorIndividual individual = new EvRealVectorIndividual(dimension);
    for(int i = 0; i < individual.getDimension() ; i++) {
     individual.setValue(i, Math.random());
    }
    individual.setObjectiveFunction(objective_function);
    return individual;
  }
  
  /** Gets dimension (length) of individuals chromosome */
  public int getDimension() {
    return dimension;
  }

  /** If only individual is from correct class and dimension, 
   * return this individual itself. In other case throw exception. */
  public EvRealVectorIndividual takeBackTo(EvRealVectorIndividual individual) {
    return individual;
  }
  
  /**
   * {@inheritDoc}
   */
  public void setObjectiveFuntion(EvObjectiveFunction<EvRealVectorIndividual> objective_function) {
    if (objective_function == null) {
      throw new IllegalArgumentException("Objective function cannot be null");
    }
    this.objective_function = objective_function;   
  }

  /**
   * {@inheritDoc}
   */
  public EvObjectiveFunction<EvRealVectorIndividual> getObjectiveFuntion() {
    return objective_function;
  }
}
